home *** CD-ROM | disk | FTP | other *** search
Java Source | 1997-06-19 | 22.0 KB | 788 lines |
- /*
- * DbaDataStore.java 1.0 12 Jan 1997
- *
- * Copyright (c) 1996 Krumel & Associates, Inc. All Rights Reserved.
- *
- * This software is provided as is. Krumel & Associates shall not be liable
- * for any damages suffered by licensee as a result of using, modifying or
- * distributing this software or its derivatives.
- */
-
- package symantec.itools.db.awt;
-
- import symantec.itools.db.pro.*;
- import symjava.sql.SQLException;
- import java.util.BitSet;
- import symjava.sql.Types;
-
- //All rows coming from DbDataSource are 0 relative
- //All cols coming from DbDataSource are 1 relative
- public class DbaDataStore implements DbDataStore, MetaTable, DbDataUpdater {
- Position position;
- RelationView master;
- RelationView relView;
- MultiView multiView;
- DbDataSource source = null;
- DbaDataLink link;
- int coltoshow=0;
- RelationViewMetaData meta;
-
- public static final int MAX_DISPLAY_SIZE = 60;
-
- public DbaDataStore(RelationView rv, RelationView masterView) throws SQLException {
- if (masterView != null)
- {
- master = masterView;
- }
- relView = rv;
- multiView = rv.getMultiView();
- meta = relView.getMetaData();
- position = new Position(rv);
- }
-
- void resetRows() throws SQLException
- {
- int count;
- // // synchronized(position)
- {
- count = position.getIgnoreCount();
- }
- if (count > 0)
- {
- return;
- }
- initRowMapping();
- source.view.clear();
- // source.view.redrawAsync(); // clear calls redrawAsync
- }
-
- void notifyRecordChange() throws SQLException
- {
- int count;
- // synchronized(position)
- {
- count = position.getIgnoreCount();
- }
- if (count > 0)
- {
- return;
- }
- int row;
- // synchronized(position)
- {
- row = position.get();
- }
-
- if (relView.getCurrentRecordState() == Record.RECSTATE_NEW)
- {
- source.view.scrollUpDownAbsolute(row -1);
- }
-
- source.view.setFocusToRow(row);
- }
-
- public void fetchMode(boolean manual)
- {
- setManRowChangeFlag(manual);
- }
-
- public boolean manualRowChangeFlag()
- {
- // synchronized (position)
- {
- return position.getNotificationMode();
- }
- }
-
- private void setManRowChangeFlag(boolean val)
- {
- try
- {
- // synchronized (position)
- {
- position.setNotificationMode(val);
- }
- }
- catch(SQLException ex) {}
- }
-
- public void setCurrentRow(int row) throws TypeNotSupported {
- row++;
- try
- {
- int translatedRow = translateRow(row);
- // synchronized (position)
- {
- position.set(translatedRow);
- }
- } catch(Exception ex)
- {
- throw new TypeNotSupported(ex.getMessage());
- }
- }
-
- public boolean isCurrentRow(int row) {
- try
- {
- int translatedRow = translateRow(row);
- // synchronized (position)
- {
- return translatedRow == position.get();
- }
- }
- catch(Exception ex)
- {
- return false;
- }
- }
-
- public void setDbDataSource(DbDataSource ds) {
- if (source != null)
- {
- return;
- }
- source = ds;
- initRowMapping();
- link = new DbaDataLink(this);
- // synchronized(position)
- {
- position.ignoreNotification(true);
- }
- try
- {
- relView.bindRecordSet(link);
- relView.bindCurrentRecord(link);
- } catch(SQLException ex) { /*this should never happend*/ }
- // synchronized(position)
- {
- position.ignoreNotification(false);
- }
- }
-
- public boolean supportsCaching() {
- return true;
- }
-
- public int validDataRowRange(int top, int bottom) throws DataNotAvailable {
- //iterate from top to bottom and find the last valid number in range
-
- //adjust for row indices being zero relative
-
- top++;
- bottom += 2; //a few extra for scrollbars
-
- int lastInRange = Math.max(1, top); //always want to ensure at least try
- //first row
-
- try {
- setManRowChangeFlag(true);
- while(lastInRange<=bottom) {
- translateRow(lastInRange);
- lastInRange++;
- }
- } catch(DataNotAvailable ex) {
- } finally {
- setManRowChangeFlag(false);
- }
-
- if (lastInRange == top) {
- throw new DataNotAvailable("top is greater than last row in database");
- }
-
- return lastInRange-1;
- }
-
- public Data getData(int row, int col) throws DataNotAvailable {
- //adjust for row indices being 0 relative
- row++;
- Data d = null;
-
- try {
- setManRowChangeFlag(true);
- int translatedRow = translateRow(row);
- boolean success;
- // synchronized(position)
- {
- success = position.set(translatedRow);
- }
- if (!success) {
- throw new DataNotAvailable("Could not move to row " + row);
- }
-
- String str = relView.getStringValue(col);
- if (str == null) { str = ""; }
- d = new ImageStringData(source, str);
- } catch(Exception ex) {
- throw new DataNotAvailable(ex.getMessage());
- } finally {
- setManRowChangeFlag(false);
- }
-
- return d;
- }
-
-
- public void update(int row, int col, Data data) throws TypeNotSupported {
- //adjust for row indices being 0 relative
- row++;
- try {
- setManRowChangeFlag(true);
- int translatedRow = translateRow(row);
- // synchronized(position)
- {
- position.set(translatedRow);
- // position.ignoreNotification(true);
- }
- //assume only string support for now
- relView.setValueFromString(col, data.toString());
- // synchronized(position)
- {
- // position.ignoreNotification(false);
- }
- } catch(Exception ex) {
- throw new TypeNotSupported(ex.getMessage());
- } finally {
- setManRowChangeFlag(false);
- }
- }
-
- public int rowState(int row)
- {
- //adjust for row indices being 0 relative
- row++;
-
- int rowState = DataSource.NEW_ROW;
- try
- {
- setManRowChangeFlag(true);
- int translatedRow = translateRow(row);
- // synchronized(position)
- {
- position.set(translatedRow);
- }
- byte state = relView.getCurrentRecordState();
- switch(state)
- {
- case Record.RECSTATE_NEW:
- rowState = DataSource. NEW_ROW; break;
- case Record.RECSTATE_DELETED:
- rowState = DataSource. DELETED_ROW; break;
- case Record.RECSTATE_MODIFIED:
- rowState = DataSource. MODIFIED_ROW; break;
- case Record.RECSTATE_EXISTING:
- rowState = DataSource. CLEAN_ROW; break;
- default:
- //now what?!?
- }
- }
- catch(Exception ex)
- {
- //if fails assume new
- ex.printStackTrace();
- }
- finally
- {
- setManRowChangeFlag(false);
- }
-
- return rowState;
- }
-
- public void clear() {
- initRowMapping(); //time to start all over
- }
-
- public void refresh() {
- try {
- relView.restartMultiView();
- } catch(SQLException ex) {
- }
- }
-
- public void undoRow(int row) throws TypeNotSupported {
- row++;
-
- try {
- // synchronized(position)
- {
- position.ignoreNotification(true);
- }
- relView.undoRecord();
- } catch(SQLException ex) {
- throw new TypeNotSupported(ex.getMessage());
- } finally {
- // synchronized(position)
- {
- position.ignoreNotification(false);
- }
- }
- }
-
- public int rowsRetrieved() {
- return lastIndex_;
- }
-
- public int fetchAllRows() {
- int count=1;
-
- try {
- setManRowChangeFlag(true);
- while(true) {
- translateRow(count);
- count++;
- }
- } catch(DataNotAvailable ex) {
- } finally {
- setManRowChangeFlag(false);
- }
-
- return count-1;
- }
-
-
- //-------------------------------------------------------------------------
- // DbUpdater Methods
- //-------------------------------------------------------------------------
-
- public void undeleteRow(int row) throws TypeNotSupported {
- try {
- row++;
- // synchronized(position)
- {
- position.ignoreNotification(true);
- }
- relView.undoRecord();
- } catch(SQLException ex) {
- throw new TypeNotSupported(ex.getMessage());
- } finally {
- // synchronized(position)
- {
- position.ignoreNotification(false);
- }
- }
- }
-
- public void deleteRow(int row) throws TypeNotSupported {
- try {
- //adjust for row indices being zero relative
- row++;
- // synchronized(position)
- {
- position.ignoreNotification(true);
- }
- relView.deleteRecord();
- } catch(SQLException ex) {
- throw new TypeNotSupported(ex.getMessage());
- } finally {
- // synchronized(position)
- {
- position.ignoreNotification(false);
- }
- }
- }
-
- public void save() throws TypeNotSupported {
- try {
- relView.saveMultiView();
- } catch(SQLException ex) {
- throw new TypeNotSupported(ex.getMessage());
- }
- }
-
- public void getNewRecord() throws TypeNotSupported
- {
- try {
- relView.getNewRecord();
- } catch(SQLException ex) {
- throw new TypeNotSupported(ex.getMessage());
- }
- }
-
- public void insertRow(int row) throws TypeNotSupported {
- appendRow();
- }
-
- public int appendRow() throws TypeNotSupported {
- /*
- // synchronized(position)
- {
- position.ignoreNotification(true);
- }
- */
- getNewRecord();
- /*
- // synchronized(position)
- {
- position.ignoreNotification(true);
- }
- */
- return 0;
- }
-
- //-------------------------------------------------------------------------
- // MetaTable Methods
- //-------------------------------------------------------------------------
- public void setColtoShow(int val){
- coltoshow=val;}
-
- public void setupGrid(Grid view) {
- try {
-
- //create the proper number of columns
- //make sure the BasicCell is set as default
- view.setAutoRedraw(false);
- //int cols = meta.getColumnCount();
- int cols = coltoshow;
- if(coltoshow==0||meta.getColumnCount()<=coltoshow)
- cols=meta.getColumnCount();
- view.createColumns(cols);
-
- //setup row headings
- view.setRowLabelHeadingStyle(Grid.AUTONUMBER);
-
- //set the column headings and widths
- for (int col=1; col<=cols; col++) {
- int size = meta.getColumnDisplaySize(col);
- size = Math.min(0, size);
- size = Math.max(0, MAX_DISPLAY_SIZE);
- view.setHeading(meta.getColumnLabel(col),
- col,
- java.lang.Math.min(size, 10));
- setupColumn(view, col);
- }
-
- view.setAutoRedraw(true);
- } catch(SQLException ex) {
- //Not much to do here but set one heading called error
- //and set the message in the first cell
- }
- }
-
- public void setDataSource(DataSource ds) { }
-
- public boolean isDataEditable(int row, int col) throws DataNotAvailable {
- try {
- //adjust for row indices being zero relative
- row++;
- setManRowChangeFlag(true);
- int translatedRow = translateRow(row);
- boolean success;
- // synchronized(position)
- {
- success = position.set(translatedRow);
- }
- if (success) {
- return meta.isWritable(col) && relView.isCurrentRecordWritable();
- }
- } catch(SQLException ex) {
- throw new DataNotAvailable(ex.getMessage());
- } finally {
- setManRowChangeFlag(false);
- }
-
- //this should never be reached
- return true;
- }
-
- public Data[] arrangeForViewing(Data data[]) {
- return data;
- }
-
- public void setupColumn(Grid view, int col) {
- //assume all cols aligned left
- try {
- int type = meta.getColumnType(col);
- switch(type) {
- case Types.BIGINT:
- case Types.INTEGER:
- case Types.DOUBLE:
- case Types.FLOAT:
- case Types.NUMERIC:
- case Types.SMALLINT:
- case Types.TINYINT:
- case Types.REAL:
- view.setColumnAlignment(col,Grid.RIGHT);
- break;
- case Types.CHAR:
- case Types.DATE:
- case Types.VARCHAR:
- case Types.LONGVARCHAR:
- case Types.NULL:
- case Types.OTHER:
- case Types.BINARY:
- case Types.VARBINARY:
- case Types.LONGVARBINARY:
- case Types.TIME:
- case Types.TIMESTAMP:
- case Types.BIT:
- default:
- view.setColumnAlignment(col,Grid.LEFT);
- }
-
- if (meta.isCurrency(col)) {
- view.setColumnAlignment(col,Grid.RIGHT);
- }
-
- if (!meta.isWritable(col)) {
- view.setColEditable(col, false);
- }
- } catch(SQLException ex) {
- //why not try a default
- view.setColumnAlignment(col,Grid.LEFT);
- }
- }
-
- //all map functions work on 1 relative rows!!!
- int rowMapping[];
- BitSet createdRows;
- int lastValidIndex;
- int lastIndex_ = 0; //pointer to last element in map,
- //waste the first
- int lastRowRetrieved = 0; //last row retrieved using position.set()
-
- boolean obtainedAllRows = false;
-
- final static int START_SIZE = 100;
- final static int INC_SIZE = 100;
-
- private void initRowMapping() {
- rowMapping = new int[START_SIZE];
- lastValidIndex = START_SIZE -1;
- lastRowRetrieved = 0;
- lastIndex_ = 0;
- obtainedAllRows = false;
- createdRows = new BitSet();
- }
-
- void printMap() {
- System.out.println("Row mappings - size="+lastValidIndex +
- "\n\tlastIndex="+lastIndex_+ " lastRow="+lastRowRetrieved);
- for(int i=0;i<=lastIndex_; i++) {
- System.out.println("\trow "+i+" -> "+rowMapping[i]);
- }
- }
-
- private int translateRow(int r) throws DataNotAvailable {
- boolean success;
- try {
- while(lastIndex_ < r) {
- //if lastRowRetrieved has already been obtained through
- //an insert then increment and keep going
- if (createdRows.get(lastRowRetrieved+1)) {
- lastRowRetrieved++;
- continue;
- }
-
- //need to fetch rows up to 'r'
-
- // synchronized(position)
- {
- success = position.set(lastRowRetrieved+1);
- }
- if (!success) {
- obtainedAllRows = true; //set the flag and boogie out
- throw new DataNotAvailable("Ran out of rows to fetch at row=" +
- (lastRowRetrieved+1));
- } else {
- //inc last row and insert into map
- lastRowRetrieved = relView.getCurrentRecordNumber();
- lastIndex_++;
- growMap();
- rowMapping[lastIndex_] = lastRowRetrieved;
- }
- }
-
- return rowMapping[r];
- } catch (SQLException e) {
- throw new DataNotAvailable(e.getMessage());
- }
- }
-
- //creates the new record and returns the translated row
- //number
- private int insertRowIntoMap(int r) throws DataNotAvailable {
- int actual;
-
- try {
- //make sure already mapped row
- translateRow(r);
-
- //create a new record
- relView.getNewRecord();
- actual = relView.getCurrentRecordNumber();
- createdRows.set(actual);
-
- //shift all array indices down one from specified row 'r'
- growMap();
- int numToCopy = lastIndex_+1-r;
- System.arraycopy(rowMapping, r, rowMapping, r+1, numToCopy);
- lastIndex_++; //we just added a row but did not retrieve one
- rowMapping[r] = actual;
- } catch(Exception e) {
- throw new DataNotAvailable(e.getMessage());
- }
-
- return actual;
- }
-
- //new row number of 1 relative
- private int appendRowIntoMap() throws DataNotAvailable {
- //record should NOT have already been created
- //before call, lastRow will be the row number
- //appended
-
- //move to end of all records
- try {
- while(!obtainedAllRows) {
- translateRow(lastRowRetrieved + 1);
- }
- } catch(DataNotAvailable ex) {
- if (!obtainedAllRows) {
- throw ex;
- }
- }
-
- //create new record
- try {
- relView.getNewRecord();
-
- //get number and insert into map
- growMap();
- lastRowRetrieved = relView.getCurrentRecordNumber();
- createdRows.set(lastRowRetrieved);
- rowMapping[++lastIndex_] = lastRowRetrieved;
- } catch(SQLException ex) {
- throw new DataNotAvailable("Could not create new record");
- }
-
- return lastIndex_;
- }
-
- final void growMap() {
- if (lastIndex_ == lastValidIndex-1) { //minus 1 for safety b/c I'm tired
- //grow array
- int newMap[] = new int[lastValidIndex+=INC_SIZE];
- System.arraycopy(rowMapping, 0, newMap, 0, rowMapping.length);
- rowMapping = newMap;
- }
- }
-
- public Object getSynchronizationObject()
- {
- return multiView;
- }
-
- }
-
- class Position
- {
- int frozenRecordNumber = 0;
- int notificationMode = 0;
- boolean frozen = false;
- RelationView relView;
- int ignoreCount = 0;
- String name = "";
-
- Position (RelationView rv)
- {
- relView = rv;
- try
- {
- name = rv.getName();
- }
- catch (SQLException e)
- {
- }
- }
-
- void freeze() throws SQLException
- {
- frozen = true;
- ignoreNotification(true);
- frozenRecordNumber = relView.getCurrentRecordNumber();
- relView.enableBindingNotify(false, true);
- relView.enableDetailSQL(false);
- }
-
- void thaw() throws SQLException
- {
- if (frozenRecordNumber > 0)
- {
- goTo(frozenRecordNumber);
- }
- relView.enableDetailSQL(true);
- relView.enableBindingNotify(true, true);
- frozen = false;
- ignoreNotification(false);
- }
-
- boolean set(int recordNumber) throws SQLException
- {
- if (relView.getCurrentRecordNumber() == recordNumber)
- {
- return true;
- }
- if (getNotificationMode() && !frozen)
- {
- freeze();
- }
- return goTo(recordNumber);
- }
-
- boolean goTo(int recordNumber) throws SQLException
- {
- boolean success = false;
- ignoreNotification(true);
- success = relView.goTo(recordNumber);
- ignoreNotification(false);
- return success;
- }
-
- int get() throws SQLException
- {
- if (frozen)
- {
- return frozenRecordNumber;
- }
- return relView.getCurrentRecordNumber();
- }
-
- void setNotificationMode(boolean mode) throws SQLException
- {
- if (mode)
- {
- notificationMode++;
- }
- else
- {
- notificationMode--;
- if (notificationMode == 0 && frozen)
- {
- thaw();
- }
- }
- }
-
- boolean getNotificationMode()
- {
- return notificationMode > 0;
- }
-
- void ignoreNotification(boolean flag)
- {
- if (flag)
- {
- ignoreCount++;
- }
- else
- {
- ignoreCount--;
- }
- }
-
- int getIgnoreCount()
- {
- return ignoreCount;
- }
-
- }